<template>
  <div class="chat-box">
    <div
      id="showBoxRef"
      class="show-box"
      :style="{ 'background-color': bgColor }"
    >
      <div
        class="box"
        v-for="(item, index) in chatData"
        :class="{ reserve: item.isSelf === 2 }"
      >
        <div class="nick-name">{{ item.create }} 张三</div>
        <div class="pic-box">
          <a-image
            :width="40"
            :src="tool.getAssetsFile('chat/girl.png')"
            :preview="false"
          >
          </a-image>
          <a-image
            :width="400"
            v-if="item.type === 2"
            :src="
              !item.content.includes('chat')
                ? item.content
                : tool.getAssetsFile(item.content)
            "
            :preview="false"
          />
          <span class="text" v-else v-html="item.content"></span>
        </div>
      </div>
    </div>
    <ChatUtil @get-emogi="getEmogi" @get-img="getImg" />
    <div class="chat-content" :style="{ 'background-color': bgColor }">
      <div
        ref="textRef"
        id="textRef"
        contenteditable="true"
        class="chat-text"
      ></div>
      <div class="send-btn">
        <a-button @click="onSend">发送</a-button>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { IChat } from "@/type/Chat";
import { message } from "ant-design-vue";
import moment from "moment";
import { useLayoutStore } from "@/store/modules/Layout";
import { computed, nextTick, onMounted, ref, watch } from "vue";
import ChatUtil from "./component/chatUtil.vue";
import tool from "@/util/imgTool.js";

const layoutStore = useLayoutStore();
const bgColor = ref("#fff");
const textRef = ref<HTMLElement>();
const chatData = ref<IChat[]>([
  {
    isSelf: 1,
    create: "2023-01-02",
    content: "无名张三，你好啊~",
    id: 1,
    type: 1,
  },
  {
    isSelf: 1,
    create: "2023-01-02",
    content: "chat/stupid.webp",
    id: 2,
    type: 2,
  },
  {
    isSelf: 2,
    create: "2023-01-02",
    content: "chat/walk.webp",
    id: 3,
    type: 2,
  },
]);
const onSend = () => {
  // 正则匹配图片
  let imgReg = /<img.*?(?:>|\/>)/gi;

  let inputValue = textRef.value?.innerHTML;
  if (!inputValue) {
    message.info({
      content: "发送内容为空",
    });
    return;
  }

  // 图片列表
  let imgList = inputValue.match(imgReg);

  let countID: number = chatData.value.length + 1;
  const chatItemImg: IChat[] =
    imgList?.map((item) => {
      let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i;
      let src = item.match(srcReg)?.length! > 0 ? item.match(srcReg)![0] : "";

      const res: IChat = {
        isSelf: 2,
        create: moment().format("yyyy-MM-DD"),
        content: src.replaceAll('src="', "").replaceAll('"', ""),
        id: countID++,
        type: 2,
      };
      return res;
    }) || [];
  chatData.value.push(...chatItemImg);

  // 文本
  let text = inputValue.replace(imgReg, "");
  if (text) {
    const resText: IChat = {
      isSelf: 2,
      create: moment().format("yyyy-MM-DD"),
      content: text,
      id: countID++,
      type: 1,
    };
    chatData.value.push(resText);
  }
  document.getElementById("textRef")!.innerHTML = "";
  let ele = document.getElementById("showBoxRef");
  if (ele) {
    nextTick(() => {
      ele!.scrollTo(ele!.scrollWidth, ele?.scrollHeight!);
    });
  }
};
const getEmogi = (content: string) => {
  let ele = document.getElementById("textRef");
  ele!.innerHTML += content;
  activeInput();
};

const cloneDeep (obj) {
  if (!obj) return;
  let newobj = {};
  let key = null;
  let data = null;
  let keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    key = keys[i];
    data = obj[key];
    if (data && typeof data === 'object') {
      newobj = cloneDeep(data);
    } else {
      newobj = data;
    }
  }
  return newobj;
}

const getImg = (imgUrl: string) => {
  const img = document.createElement("img");
  img.src = imgUrl;
  const res = `<img width="300" src=${imgUrl}>`;
  getEmogi(res);
};

const activeInput = () => {
  let ele = document.getElementById("textRef");
  if (ele) {
    keepLastIndex(ele);
  }
};

/**
 * 光标保持在最后
 * @param obj
 */
const keepLastIndex = (obj: HTMLElement) => {
  if (window.getSelection) {
    // ie11 10 9 ff safari
    obj.focus(); // 解决ff不获取焦点无法定位问题
    let range = window.getSelection(); // 创建range
    range?.selectAllChildren(obj); // range 选择obj下所有子内容
    range?.collapseToEnd(); // 光标移至最后
  }
};

watch(
  () => layoutStore.$state.themeType,
  (newVal) => {
    bgColor.value = newVal === "default" ? "#fff" : "#000";
  }
);

onMounted(() => {
  nextTick(() => {
    activeInput();
  });
});
</script>
<style lang="less" rel="stylesheet/less" scoped>
.chat-box {
  height: 100%;
  display: flex;
  flex-direction: column;

  .show-box {
    height: 60%;
    max-height: 60%;
    overflow-y: scroll;
    background-color: #f7f6f4;
    padding: 10px;

    .box {
      margin: 20px 0;

      .nick-name {
        color: #b4b4b4;
        font-size: 12px;
        margin-bottom: 5px;
      }

      .pic-box {
        display: flex;

        :nth-child(2) {
          margin-left: 10px;
          line-height: 40px;
        }

        .text {
          background-color: #7d83ab;
          border-radius: 10px;
          padding: 6px;
          font-size: 14px;
        }
      }
    }

    .reserve {
      display: flex;
      flex-direction: column;
      align-items: flex-end;

      .pic-box {
        flex-direction: row-reverse;

        :nth-child(2) {
          margin: 0;
          margin-right: 10px;
        }
      }
    }
  }

  .chat-content {
    height: 30%;
    overflow-y: scroll;
    background-color: #f7f6f4;
    padding: 10px;

    .chat-text {
      height: 70%;
      overflow-y: scroll;
      padding: 6px;
      border-radius: 10px;
      border: 1px solid #40a9ff;
      outline-style: none; // 设置外轮廓
    }

    .send-btn {
      float: right;
      margin: 10px;
    }

    :deep(.ant-input) {
      border: 1px solid;
      border-color: rgba(0, 0, 0, 0);
      background-color: #f7f6f4;
    }

    :deep(.ant-input:focus, .ant-input-focused) {
      box-shadow: 0 !important;
      border: 1px solid #40a9ff;
    }
  }
}
</style>
